package ai

import (
	"container/list"
)

type Cache[T any] struct {
	capacity int
	cache    *list.List
	mapCache map[uint64]T
}

func NewCache[T any](capacity int) *Cache[T] {
	return &Cache[T]{
		capacity: capacity,
		cache:    list.New(),
		mapCache: make(map[uint64]T),
	}
}

func (c *Cache[T]) get(key uint64) *T {
	if val, ok := c.mapCache[key]; ok {
		return &val
	}
	return nil
}

func (c *Cache[T]) put(key uint64, value T) {
	if c.cache.Len() >= c.capacity {
		oldest := c.cache.Back()
		c.cache.Remove(oldest)
		delete(c.mapCache, oldest.Value.(uint64))
	}

	if _, ok := c.mapCache[key]; !ok {
		c.cache.PushFront(key)
	}
	c.mapCache[key] = value
}

func (c *Cache[T]) has(key uint64) bool {
	_, ok := c.mapCache[key]
	return ok
}
